﻿using System;
//using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Threading.Tasks;

namespace Merge_sort
{
    public partial class Form1 : Form
    {
        const int size = 10;
        const int max = size * 10;
        List<int> array = new List<int>();
        List<int> original;
        Random rand = new Random();
        bool noUpdate = false;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
        }

        private void Randomize_Click(object sender, EventArgs e)
        {
            while (array.Count < size)
            {
                int n = rand.Next(max);
                if (!array.Contains(n))
                    array.Add(n);
            }
            Update_text(array);
            MessageBox.Show("Done!");
        }

        private void Update_text(List<int> arr)
        {
            Txt.Text = "";
            if (noUpdate)
                return;
            foreach (int i in arr)
                Txt.Text += i.ToString() + ", ";
        }

        private void Check_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < array.Count - 1; i++)
            {
                if (array[i] > array[i + 1])
                {
                    MessageBox.Show("Not sorted!", "Checked");
                    return;
                }
            }
            MessageBox.Show("Sorted!", "Checked");
        }

        private void Single_Click(object sender, EventArgs e)
        {
            original = new List<int>();
            foreach (int i in array)
                original.Add(i);
            DateTime dt = DateTime.Now;
            int n = array.Count;
            array = MergeSort(array);
            MessageBox.Show((DateTime.Now - dt).ToString());
            Update_text(array);
            //MessageBox.Show((DateTime.Now - dt).ToString());
            
        }
        private List<int> Merge(List<int> arr1, List<int> arr2)
        {
            List<int> retVal = new List<int>();
            int i = 0, j = 0;
            while (i < arr1.Count && j < arr2.Count)
            {
                if (arr1[i] <= arr2[j])
                {
                    retVal.Add(arr1[i]);
                    i++;
                }
                else
                {
                    retVal.Add(arr2[j]);
                    j++;
                }
            }
            for (; i < arr1.Count; i++)
                retVal.Add(arr1[i]);
            for (; j < arr2.Count; j++)
                retVal.Add(arr2[j]);
            return retVal;
        }

        private List<int> MergeSort(List<int> arr)
        {
            if (arr.Count == 1)
            {
                Thread.Sleep(1);
                return arr;
            }
            else
                return Merge(MergeSort(arr.Take(arr.Count / 2).ToList()), MergeSort(arr.Skip(arr.Count / 2).ToList()));
        }

        private void Reset_Click(object sender, EventArgs e)
        {
            array = original;
            Update_text(array);
        }

        private List<int> MultiMergeSort(List<int> arr)
        {
            if (arr.Count == 1)
            {
                Thread.Sleep(1);
                return arr;
            }
            else
            {
                List<int> arr1 = Task<List<int>>.Factory.StartNew(() => MultiMergeSort(arr.Take(arr.Count / 2).ToList())).Result;
                List<int> arr2 = Task<List<int>>.Factory.StartNew(() => MultiMergeSort(arr.Skip(arr.Count / 2).ToList())).Result;
                return Merge(arr1, arr2);
            }
        }

        private void Multi_Click(object sender, EventArgs e)
        {
            original = new List<int>();
            foreach (int i in array)
                original.Add(i);
            DateTime dt = DateTime.Now;
            int n = array.Count;
            array = MultiMergeSort(array);
            MessageBox.Show((DateTime.Now - dt).ToString());
            Update_text(array);
            //MessageBox.Show((DateTime.Now - dt).ToString());
        }
    }
}
